﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Reflection;
using System.Diagnostics;

namespace IMLibrary.Security
{
    /// <summary>
    /// 加密
    /// </summary>
    public class Encryption
    {
        private   static  byte[] NullData = new byte[0];
        public static byte[] EncryptionKey  = { 0x14, 0x24, 0x16, 0x18, 0x91, 0xAC, 0xCE, 0xEC, 0x22, 0x44, 0x46, 0x28, 0x30, 0xAB, 0xCE, 0xEE };   

        #region 3DES方法
        /// <summary>
        /// 3DES加密
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string Encrypt3DES(string password)
        {
            return Convert.ToBase64String(Encrypt3DES(Encoding.UTF8.GetBytes(password), EncryptionKey));    
        }
        /// <summary>
        /// 3DES解密
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string Decrypt3DES(string password)
        {
            return Encoding.UTF8.GetString(Decrypt3DES(Convert.FromBase64String(password), EncryptionKey));
        }
        /// <summary>
        /// 3DES加密
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public static byte[] Encrypt3DES(byte[] Data)
        {
            if (Data == null || Data.Length == 0)
                return Data;
            return Encrypt3DES(Data, EncryptionKey);
        }
        /// <summary>
        /// 3DES加密
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] Encrypt3DES(byte[] Data, byte[] key)
        {
            if (Data == null || Data.Length == 0)
                return Data;
            byte[] result = NullData;
            try
            {
                TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
                provider.Key = key ;
                provider.Mode = CipherMode.ECB;
                MemoryStream stream = new MemoryStream();
                ICryptoTransform transform = provider.CreateEncryptor();
                CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
                stream2.Write(Data, 0, Data.Length);
                stream2.FlushFinalBlock();
                result =stream.ToArray(); 
                stream.Flush();
                stream.Close();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error:" + ex.Message);
            }

            return result;
        }
        /// <summary>
        /// 3DES解密
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public static byte[] Decrypt3DES(byte[] Data)
        {
            if (Data == null || Data.Length == 0)
                return Data;
            return Decrypt3DES(Data,EncryptionKey);
        }
        /// <summary>
        /// 3DES解密
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] Decrypt3DES(byte[] Data, byte[] key)
        {
            if (Data == null || Data.Length == 0)
                return Data;
            byte[] result = NullData;
            try
            {
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider(); 
                des.Key = key; 
                des.Mode = CipherMode.ECB;
                MemoryStream ms = new MemoryStream();
                ICryptoTransform transform = des.CreateDecryptor();
                CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
                cs.Write(Data, 0, Data.Length);
                cs.FlushFinalBlock();
                result = ms.ToArray(); 
                ms.Flush();
                ms.Close();

            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error:"+ ex.Message);
            }
            return result;
        }
        #endregion

        #region AES方法 
        /// <summary>  
        /// AES加密算法  
        /// </summary>  
        /// <param name="Data">明文字符串</param>  
        /// <param name="Key">密钥</param>  
        /// <returns>返回加密后的密文字节数组</returns>  
        public static byte[] EncryptAES(byte[] Data, byte[] Key)
        {
            if (Data == null || Data.Length == 0)
                return Data;
            try
            {
                //分组加密算法  
                SymmetricAlgorithm des = Rijndael.Create();
                //设置密钥及密钥向量  
                des.Key = Key;
                des.IV = EncryptionKey;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(Data, 0, Data.Length);
                cs.FlushFinalBlock();
                byte[] cipherBytes = ms.ToArray();//得到加密后的字节数组  
                cs.Close();
                ms.Close();
                return cipherBytes;
            }
            catch { return NullData; }
        }
          
        /// <summary>  
        /// AES解密  
        /// </summary>  
        /// <param name="Data">密文字节数组</param>  
        /// <param name="Key">密钥</param>  
        /// <returns>返回解密后的字符串</returns>  
        public static byte[] DecryptAES(byte[] Data, byte[] Key)
        {
            if (Data == null || Data.Length == 0)
                return Data;
            try
            {
                SymmetricAlgorithm des = Rijndael.Create();
                des.Key = Key;
                des.IV = EncryptionKey;
                byte[] decryptBytes = new byte[Data.Length];
                MemoryStream ms = new MemoryStream(Data);
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
                cs.Read(decryptBytes, 0, decryptBytes.Length);
                cs.Close();
                ms.Close();
                return decryptBytes;
            }
            catch { return NullData; }
        }
        #endregion
    }
}
